#include "ZenCamera.h"

CZenCamera::CZenCamera():m_bLookPoint(false)
{
	m_Position	= D3DXVECTOR3(0.0f, 0.0f, -1.0f);
	m_Velocity	= D3DXVECTOR3(0.0f, 0.0f,  0.0f);
	m_LookVector= D3DXVECTOR3(0.0f, 0.0f, -1.0f);
	m_Right		= D3DXVECTOR3(1.0f, 0.0f,  0.0f);
	m_Up		= D3DXVECTOR3(0.0f, 1.0f,  0.0f);

	m_Roll = m_Pitch = m_Yaw = 0.0f;
}

CZenCamera::~CZenCamera()
{
}

void CZenCamera::Reset()
{
	m_Position  = D3DXVECTOR3(0.0f, 1.0f, 5.0f);
	m_Velocity	= D3DXVECTOR3(0.0f, 0.0f, 0.0f);
	m_LookVector= D3DXVECTOR3(0.0f, 0.0f,-5.0f);
	m_Right		= D3DXVECTOR3(1.0f, 0.0f, 0.0f);
	m_Up		= D3DXVECTOR3(0.0f, 1.0f, 0.0f);

}

void CZenCamera::Move(float x, float y, float z)
{
	m_Position.x = x;
	m_Position.y = y;
	m_Position.z = z;
}

void CZenCamera::SetPosition(float x, float y, float z)
{
	float lx,ly,lz;

	m_Position.x = x;
	m_Position.y = y;
	m_Position.z = z;

	if (m_bLookPoint)
	{
		GetLookPoint(lx, ly, lz);
		SetLookPoint(lx, ly, lz);
	}
}

void CZenCamera::GetPosition(float &x, float &y, float &z)
{
	x = m_Position.x;
	y = m_Position.y;
	z = m_Position.z;
}

void CZenCamera::SetRoll(float Roll)
{
	m_Roll = Roll;
}

void CZenCamera::GetRoll(float &Roll)
{
	Roll = m_Roll;
}

void CZenCamera::GetYaw(float &Yaw)
{
	Yaw = m_Yaw;
}

void CZenCamera::SetYaw(float Yaw)
{
	m_Yaw = Yaw;
}

void CZenCamera::GetPitch(float &Pitch)
{
	Pitch = m_Pitch;
}

void CZenCamera::SetPitch(float Pitch)
{
	m_Pitch = Pitch;
}

void CZenCamera::SetLookVector(float x, float y, float z)
{
	m_bLookPoint = false;

	m_LookVector.x = x;
	m_LookVector.y = y;
	m_LookVector.z = z;
}

void CZenCamera::GetLookVector(float &x, float &y, float &z)
{
	x = m_LookVector.x;
	y = m_LookVector.y;
	z = m_LookVector.z;
}

void CZenCamera::SetLookPoint(float x, float y, float z)
{
	m_bLookPoint = true;

	//Een wat handigere lookat functie --> het is makkelijker, wanneer 
	//je aangeeft WAAR je naar toe kijkt op bepaalde momenten
	this->m_LookPoint.x=x;
	this->m_LookVector.x=x-this->m_Position.x;
	this->m_LookPoint.y=y;
	this->m_LookVector.y=y-this->m_Position.y;
	this->m_LookPoint.z=z;
	this->m_LookVector.z=z-this->m_Position.z;
	
	D3DXVec3Normalize(&this->m_LookVector,&this->m_LookVector);

}

void CZenCamera::GetLookPoint(float &x, float &y, float &z)
{
	x = m_LookPoint.x;
	y = m_LookPoint.y;
	z = m_LookPoint.z;	
}

void CZenCamera::SetUp(float x, float y, float z)
{
	m_Up.x = x;
	m_Up.y = y;
	m_Up.z = z;
}

void CZenCamera::GetUp(	float &x, float &y, float &z)
{
	x = m_Up.x;
	y = m_Up.y;
	z = m_Up.z;
}

void CZenCamera::SetVelocity(float x, float y, float z)
{
	m_Velocity.x = x;
	m_Velocity.y = y;
	m_Velocity.z = z;
}

void CZenCamera::GetVelocity(float &x, float &y, float &z)
{
	x = m_Velocity.x;
	y = m_Velocity.y;
	z = m_Velocity.z;
}

void CZenCamera::SetRight(float x, float y, float z)
{
	m_Right.x = x;
	m_Right.y = y;
	m_Right.z = z;
}

void CZenCamera::GetRight(float &x, float &y, float &z)
{
	x = m_Right.x;
	y = m_Right.y;
	z = m_Right.z;
}

void CZenCamera::Update()
{
	// Update the x position
	m_Position.x += m_Velocity.x * m_Right.x;
	m_Position.y += m_Velocity.x * m_Right.y;
	m_Position.z += m_Velocity.x * m_Right.z;

	// Update the y position
	m_Position.x += m_Velocity.y * m_Up.x;
	m_Position.y += m_Velocity.y * m_Up.y;
	m_Position.z += m_Velocity.y * m_Up.z;
	
	// Update the z position
	m_Position.x += m_Velocity.z * m_LookVector.x;
	m_Position.y += m_Velocity.z * m_LookVector.y;
	m_Position.z += m_Velocity.z * m_LookVector.z;
	
	D3DXMATRIX mPitch, mRoll, mYaw;
	
	// Normalize and Regenerate the Look, Right, and Up Vectors
	D3DXVec3Normalize( &m_LookVector, &m_LookVector );
	D3DXVec3Cross( &m_Right, &m_Up, &m_LookVector );
	D3DXVec3Normalize( &m_Right, &m_Right );
	D3DXVec3Cross( &m_Up, &m_LookVector, &m_Right );
	D3DXVec3Normalize( &m_Up, &m_Up );
	
	// Set up the y-axis rotation
	D3DXMatrixRotationAxis( &mYaw, &m_Up, m_Yaw );
	D3DXVec3TransformCoord( &m_LookVector, &m_LookVector, &mYaw );
	D3DXVec3TransformCoord( &m_Right, &m_Right, &mYaw );

	// Set up the x-axis rotation
	D3DXMatrixRotationAxis( &mPitch, &m_Right, m_Pitch );
	D3DXVec3TransformCoord( &m_LookVector, &m_LookVector, &mPitch );
	D3DXVec3TransformCoord( &m_Up, &m_Up, &mPitch );

	// Set up the z-axis rotation
	D3DXMatrixRotationAxis( &mRoll, &m_LookVector, m_Roll );
	D3DXVec3TransformCoord( &m_Right, &m_Right, &mRoll );
	D3DXVec3TransformCoord( &m_Up, &m_Up, &mRoll );

	D3DXMATRIX mView;

	// Init the view matrix to an identity
	D3DXMatrixIdentity( &mView );

	// Fill in the view matrix 
	mView(0,0) = m_Right.x;	
	mView(0,1) = m_Up.x;
	mView(0,2) = m_LookVector.x;

	mView(1,0) = m_Right.y;
	mView(1,1) = m_Up.y;
	mView(1,2) = m_LookVector.y;

	mView(2,0) = m_Right.z;
	mView(2,1) = m_Up.z;
	mView(2,2) = m_LookVector.z;

	mView(3,0) = - D3DXVec3Dot( &m_Position, &m_Right );
	mView(3,1) = - D3DXVec3Dot( &m_Position, &m_Up );
	mView(3,2) = - D3DXVec3Dot( &m_Position, &m_LookVector );

	// Set the view matrix
	zen.m_pDevice->SetTransform( D3DTS_VIEW, &mView );
}

HRESULT CZenCamera::Render()
{
	return S_OK;
}

int CZenCamera::GetSize()
{
	return sizeof(*this);
}
